/* =========================================================================
 * File: GetPutRemoveThread.java$
 *
 * Modified by Saverio Miroddi
 *
 * =========================================================================
 * Copyright 2006 by Yuriy Stepovoy.
 * email: stepovoy@gmail.com
 * All rights reserved.
 * =========================================================================
 */
package net.sf.cache4j.perfomance.test;

import net.sf.cache4j.perfomance.cache.ICacheTest;

public class GetPutRemoveThread implements ITest {
    private static final String NAME = "GetPutRemoveT";

    private static final int TOT_KEYS = 2000;
    private static final int KEYS_RANGE = 2000;

    private static String[] KEYS = Utils.getRandomKeys(TOT_KEYS, KEYS_RANGE);
    
    private static final int THREADS_NUM = 10;
    private static final int THREAD_TOT_KEYS = 100000;
    private static final int THREAD_KEYS_RANGE = 2000;

    private static String[] THREAD_KEYS = 
    	Utils.getRandomKeys(THREAD_TOT_KEYS, THREAD_KEYS_RANGE);
    
    private ICacheTest cache;
    private int[] threadsSemaphore; 
    
    public void init(ICacheTest cache) throws Exception {
        this.cache = cache;
        threadsSemaphore = new int[] { THREADS_NUM };
        for (String key: KEYS) cache.put(key, key);
    }

    public void test() throws Exception {
        for (int i = 0; i < THREADS_NUM; i++) new TThread().start();            
        
        synchronized(threadsSemaphore) {
        	while (threadsSemaphore[0] > 0) {
        		threadsSemaphore.wait();
        	}
        }
    }

    public String getName() {
        return NAME;
    }

    private class TThread extends Thread {
        public void run() {
            try {
            	for (String key: THREAD_KEYS) {
        			Object retrieved = cache.get(key);
        			
        			if (retrieved == null) {
                        cache.put(key, key);
        			}
        			else {
        				cache.remove(key);
        			}
            	}
            }
            catch (Exception e){
                throw new RuntimeException(e);
            }
            finally {
                threadsSemaphore[0]--;
                synchronized(threadsSemaphore) {
                	threadsSemaphore.notifyAll();
                }
            }
        }
    }

	public void destroy() {
		cache.destroy();
	}
}